package gazzera.node.core;

import gazzera.gui.*;
import gazzera.node.core.messages.*;
import gazzera.node.core.peer.*;

/**
 * This is a generic Plugin interface implementing a funtionality on the Core.
 * All functionalities (browsing, downloading, chatting, etc) are modularized
 * into plugins
 * 
 */
public interface Plugin
{

    /**
     * Handle a message arrived from a node. If the plugin is uninterested, it should do nothing.
     * @param node the source node
     * @param msg the message arrived
     * @throws Exception
     */
    void message(Node node, Message msg) throws Exception;

    /**
     * Respond to a command from the GUI
     * @param msg the command.
     * @throws Exception
     */
    void command(GuiMessage msg) throws Exception;

    /**
     * Here the plugin should initialize himself.
     * Note: this initialization should be local only: the plugin can't count on any other
     * component of the program being initialized. It should be ready to receive any request
     * after returning from this method.
     * @param core
     * @throws Exception
     */
    void init(ICore core) throws Exception;

    /**
     * The plugin must terminate cleanly. Valid assumptions: <li>all peer's
     * sockets will be closed <li>you can still enqueue on peers, but message
     * will be lost <li>your Tasks will be already terminated even if you didn't
     * received the TaskTerminated event <li>Datapumps will be already
     * terminated even if you didn't reveived the DataPumpTerminated event
     * 
     * @throws Exception
     */
    void finish() throws Exception;

    /**
     * The core has started correcly. Here you can start any activity that
     * require to communicate with other components.
     * All plugins, the core or the gui are already initialized when this method is called.
     * @throws Exception
     */
    void start() throws Exception;

    /**
     * A datapump have terminated. Note that you receive this message even from
     * datapumps that have been started from other plugins.
     * @param node the node whose datapump has terminated
     * @param src the terminated datapump
     * @throws Exception
     */
    void dataPumpTerminated(Node node, DataPumpSource src) throws Exception;

    /**
     * A task has terminated. Note that you receive this message even from
     * tasks that have been started from other plugins.
     * @param task the terminated task
     * @param interrupted whetere the task has terminated cleanly or has been interrupted
     * by other threads or by and exception.
     * @throws Exception
     */
    void taskTerminated(Task task, boolean interrupted) throws Exception;

    /**
     * A new node has connected.
     * @param node the connected node.
     * @throws Exception
     */
    void nodeConnected(Node node) throws Exception;

    /**
     * A node has disconnected. All references to the node must be cleaned before 
     * exiting this method. It is an error to use any of this node's method after this method.
     * @param node
     * @throws Exception
     */
    void nodeDisconnected(Node node) throws Exception;
}
